/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sgt.onlinetest.controller.test;

import java.io.IOException;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import sgt.onlinetest.controller.XServlet;
import sgt.onlinetest.entity.*;
import sgt.onlinetest.hibernatedao.HibernateDAOFactory;
import sgt.onlinetest.util.Converter;
import sgt.onlinetest.util.RandomHelper;
import sgt.onlinetest.util.ServletExtension;

/**
 *
 * @author Administrator
 */
public class GenerateTestSession extends XServlet {

    private final int TEST_PASSWORD_LENGTH = 4;

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    private boolean changeSelectedQuestions(HttpServletRequest request, HibernateDAOFactory factory, List<Question> selectedQuestions) {
        if (request.getMethod().equalsIgnoreCase("POST")) {
            //process any post back
            if (request.getParameter("add") != null) {
                //call to add a single question to selected list
                Long idToAdd = ServletExtension.getLongParam(request, "idToAdd");
                Question qToAdd = factory.getQuestionDAO().getById(idToAdd);
                selectedQuestions.add(qToAdd);
            } else if (request.getParameter("addMany") != null && request.getParameterValues("idToAddMany") != null) {
                for (String strIdToAdd : request.getParameterValues("idToAddMany")) {
                    selectedQuestions.add(factory.getQuestionDAO().getById(Converter.toLong(strIdToAdd)));
                }
            } else if (request.getParameter("remove") != null) {
                Long idToRemove = ServletExtension.getLongParam(request, "idToRemove");
                for (int i = 0; i < selectedQuestions.size(); i++) {
                    if (selectedQuestions.get(i).getAutoId() == idToRemove) {
                        selectedQuestions.remove(i);
                        break;
                    }
                }
            } else if (request.getParameter("removeMany") != null && request.getParameterValues("idToRemoveMany") != null) {
                List<Long> idToRemoveMany = new ArrayList<Long>();
                for (String id : request.getParameterValues("idToRemoveMany")) {
                    idToRemoveMany.add(Converter.toLong(id));
                }
                List<Question> tmp = new ArrayList<Question>(selectedQuestions);
                for (Question q : tmp) {
                    if (idToRemoveMany.contains(q.getAutoId())) {
                        selectedQuestions.remove(q);
                    }
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
        return true;
    }

    private boolean generateTestSession(HttpServletRequest request, HibernateDAOFactory factory, List<Question> selectedQuestions) {
        if (request.getMethod().equalsIgnoreCase("POST")) {
            if (request.getParameter("generate") != null) {
                TestSession session = new TestSession();
                int questionsPerTest = ServletExtension.getIntParam(request, "questionsPerTest");
                String[] accounts = ServletExtension.getStringParam(request, "accounts").split("[\\s|;\\r\\n]");
                for (String a : accounts) {
                    if (!a.isEmpty()) {
                        Test t = new Test();
                        t.setLoginIdentity(a);
                        t.setLoginPassword(RandomHelper.getRndString(TEST_PASSWORD_LENGTH));
                        t.addQuestionRange(RandomHelper.getRndSubSet(selectedQuestions, questionsPerTest));
                        session.addTest(t);
                    }
                }
                session.setName(request.getParameter("name"));
                factory.getTestSessionDAO().save(session);

            } else {
                return false;
            }
        } else {
            return false;
        }
        return true;
    }

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HibernateDAOFactory factory = new HibernateDAOFactory();
        long catId = ServletExtension.getLongParam(request, "catId");
        QuestionCategory category = catId != 0 ? factory.getQuestionCategoryDAO().getById(catId) : factory.getQuestionCategoryDAO().getRoot();
        request.setAttribute("category", category);//pass category to the view
        List<Question> questions = factory.getQuestionDAO().getByCategory(category);
        List<Question> selectedQuestions = (List<Question>) request.getSession().getAttribute("selectedQuestions");
        if (selectedQuestions == null) {
            selectedQuestions = new ArrayList<Question>();
            request.getSession().setAttribute("selectedQuestions", selectedQuestions);
        }

        if (!changeSelectedQuestions(request, factory, selectedQuestions)) {
            if (generateTestSession(request, factory, selectedQuestions)) {
                response.sendRedirect(request.getContextPath() + "/test/listSessions");
                return;
            }
        }

        List<Long> selectedQuestionIds = new ArrayList<Long>();
        for (Question q1 : selectedQuestions) {
            selectedQuestionIds.add(q1.getAutoId());
        }
        List<Question> tmp = new ArrayList<Question>(questions);//clone questions to a new list for purpose of referencing
        for (Question q2 : tmp) {
            if (selectedQuestionIds.indexOf(q2.getAutoId()) != -1) {
                questions.remove(q2);//remove selected question from available question list for clear-view
            }
        }
        request.setAttribute("questions", questions);
        request.setAttribute("title", "Generate test session");
        request.getRequestDispatcher("/test.generateSession.tiles").forward(request, response);
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
